package com.jushu.storbox.manager;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import android.content.Context;

import com.jushu.storbox.constant.Constant;
import com.jushu.storbox.database.DAOFactory;
import com.jushu.storbox.entities.UploadObject;
import com.jushu.storbox.task.tqueue.UploadPriorityTaskScheduler;
import com.jushu.storbox.task.tqueue.UploadTask;

public class UploadTaskManager{
	private static final int POOL_SIZE = 3;
	private static final Set<UploadTask> uploadSet = new HashSet<UploadTask>();
	private static final UploadPriorityTaskScheduler<UploadTask> uploadSequence = new UploadPriorityTaskScheduler<UploadTask>(POOL_SIZE);
	private static final Set<UploadTask> failedSet = new HashSet<UploadTask>();
	private static final Set<UploadTask> runningSet = new HashSet<UploadTask>();
	private static final Set<UploadTask> waitingSet = new HashSet<UploadTask>();//waiting
	
//	public void 
	
	public static Set<UploadTask> getAllTaskes() {
		return  new HashSet<UploadTask>(uploadSet);
	}
	
	public static Set<UploadTask> getAllRunningTaskes() {
		return  new HashSet<UploadTask>(runningSet);
	}
	
	public static Set<UploadTask> getAllWaitingTaskes() {
		return  new HashSet<UploadTask>(waitingSet);
	}
	
	public static Set<UploadTask> getAllFailTaskes() {
		return  new HashSet<UploadTask>(failedSet);
	}
	
	public static Set<UploadTask> getAllTaskes(String folderID) {
		Set<UploadTask> tasks = new HashSet<UploadTask>();
		for(Iterator<UploadTask> itor = uploadSet.iterator(); itor.hasNext();) {
			UploadTask task = itor.next();
			if (folderID.equalsIgnoreCase(task.getFolderID()))
				tasks.add(task);
		}
		return tasks;
	}
	
	public static void stop() {
		uploadSequence.stop();
	}
	
	public static void start() {
		uploadSequence.start();
	}
	
	public static boolean addTask(UploadTask task) {
		synchronized (uploadSet) {
			if (10 >= uploadSet.size() && uploadSet.add(task) && waitingSet.add(task)) {
				uploadSequence.runTask(task);
				return true;//add success
			} else {
				return false;//add fail
			}
		}
	}
	
	/**
	 * @param id
	 * @return
	 * the right method is {@link #getTask(String,String)}}
	 */
	@Deprecated
	public static UploadTask getTask(String id) {
		UploadTask task = null;
		for(Iterator<UploadTask> itor = uploadSet.iterator(); itor.hasNext();) {
			task = itor.next();
			if (id.equalsIgnoreCase(task.getId()))
				return task;
		}
		return null;
	}
	
	public static boolean isRunning(UploadTask task) {
		synchronized (runningSet) {
			return runningSet.contains(task);
		}
	}
	
	public static boolean contains(UploadTask task) {
		synchronized (uploadSet) {
			return uploadSet.contains(task);
		}
	}
	
	public static boolean isWaiting(UploadTask task) {
		synchronized (waitingSet) {
			return waitingSet.contains(task);
		}
	}
	
	public static boolean removeTask(UploadTask task) {
		uploadSequence.removeTask(task);
		removeRunningTask(task);
		removeWaitingTask(task);
		synchronized (uploadSet) {
			return uploadSet.remove(task);
		}
	}
	//
	public static boolean addRunningTask(UploadTask task) {
		synchronized (runningSet) {
			return runningSet.add(task);
		}
	}
	
	public static boolean removeRunningTask(UploadTask task) {
		synchronized (runningSet) {
			return runningSet.remove(task);
		}
	}
	
	public static boolean addFailTask(UploadTask task) {
		synchronized (failedSet) {
			return failedSet.add(task);
		}
	}
	
	public static boolean removeFailTask(UploadTask task) {
		synchronized (failedSet) {
			return failedSet.remove(task);
		}
	}
	
	public static void startTask(Context context, UploadObject uploadItem) {
		if(uploadItem == null) {
			return;
		}
		
		UploadTask uploadTask = getTask(uploadItem.getOwnerId(), uploadItem.getParent(), uploadItem.getLoctPath());
		if(uploadTask == null) {
			addTask(new UploadTask(context, uploadItem, null));
		}
	}
	
	public static void stopTask(Context context, UploadObject uploadItem) {
		if(uploadItem == null) {
			return;
		}
		
		UploadTask uploadTask = getTask(uploadItem.getOwnerId(), uploadItem.getParent(), uploadItem.getLoctPath());
		if(uploadTask != null) {
			uploadTask.stopUploadTask();
			removeTask(uploadTask);
		} else {
			uploadItem.setTransStatus(Constant.TRANSLATE_IS_STOPED);
			uploadItem.notifyChange();
			DAOFactory.instance(context).getUploadFileDao()
				.updateUploadObject(uploadItem);
		}
	}
	
	public static void cancelTask(Context context, UploadObject uploadItem) {
		if(uploadItem == null) {
			return;
		}
		
		UploadTask uploadTask = getTask(uploadItem.getOwnerId(), uploadItem.getParent(), uploadItem.getLoctPath());
		if(uploadTask != null) {
			uploadTask.cancelUploadTask();
			removeTask(uploadTask);
		} else {
			DAOFactory.instance(context).getUploadFileDao()
				.deleteFile(uploadItem);
		}
	}
	//
	public static boolean addWaitingTask(UploadTask task) {
		synchronized (waitingSet) {
			return waitingSet.add(task);
		}
	}
	
	public static boolean removeWaitingTask(UploadTask task) {
		synchronized (waitingSet) {
			return waitingSet.remove(task);
		}
	}
	
	public static void cancelAllTask() {
//		HashSet<UploadTask> tempUploadSet = new HashSet<UploadTask>();
//		synchronized(uploadSet) {
//			tempUploadSet.addAll(uploadSet);
//		}
//		
//		for(UploadTask u : tempUploadSet) {
//			u.stopUploadTask();
//		}
		synchronized(uploadSet) {
			for( UploadTask u: uploadSet) {
				u.stopUploadTask();
			}
		}
	}
	
	public static UploadTask getTask(UploadObject uploadItem) {
		return getTask(
				uploadItem.getOwnerId(), 
				uploadItem.getParent(), 
				uploadItem.getLoctPath());
	}
		

	public static UploadTask getTask(String ownerId, String folderId, String filePath) {
		String tempOwnerId = "";
		String tempParentId = "";
		String tempLocalPath = "";
		for(UploadTask task : uploadSet) {
			if(task != null ) {
				tempOwnerId = task.getOwnerId();
				tempParentId = task.getFolderID();
				tempLocalPath = task.getFilePath();
				if ( tempOwnerId.equalsIgnoreCase(ownerId)
					&& tempParentId.equalsIgnoreCase(folderId)
					&& tempLocalPath.equalsIgnoreCase(filePath)) {
					return task;
				}
			}
		}
		return null;
	}
	
	public static UploadTask getFailureTask(String folderId, String filePath) {
		UploadTask task = null;
		for(Iterator<UploadTask> itor = failedSet.iterator(); itor.hasNext();) {
			task = itor.next();
			if (task.getId().equalsIgnoreCase(filePath)
					&& task.getFolderID().equalsIgnoreCase(folderId)) {
				itor.remove();
				return task;
			}
		}
		return null;
	}
}
